<!-- Proxy Create Form-->
<style>
    .rulesInstructions{
        background: var(--theme_background) !important; 
        color: var(--theme_lgrey);
        border-radius: 1em !important;
    }

    .ui.form .sub.field{
        background-color: var(--theme_advance);
        border-radius: 0.6em;
        padding: 1em;
    }

    .descheader{
        display:none !important;
    }

    @media (min-width: 1367px) {
        .descheader{
            display:auto !important;

        }
    }
</style>
<div class="standardContainer">
    <div class="ui stackable grid">
        <div class="ten wide column">
            <div class="ui basic segment" style="border-radius: 1em; padding: 1em !important;">
                <h2>New Proxy Rule</h2>
                <p>You can add more proxy rules to support more site via domain / subdomains</p>
                <div class="ui form">
                    <div class="field" tourstep="matchingkeyword">
                        <label>Matching Keyword / Domain</label>
                        <input type="text" id="rootname" placeholder="mydomain.com">
                        <small>Support subdomain and wildcard, e.g. s1.mydomain.com or *.test.mydomain.com. Use comma (,) for alias hostnames. </small>
                    </div>
                    <div class="field" tourstep="targetdomain">
                        <label>Target IP Address or Domain Name with port</label>
                            <input type="text" id="proxyDomain" onchange="autoFillTargetTLS(this);">
                        <small>e.g. 192.168.0.101:8000 or example.com</small>
                    </div>
                    <div class="field dockerOptimizations" style="display:none;">
                        <button style="margin-top: -2em;" class="ui basic small button" onclick="openDockerContainersList();"><i class="blue docker icon"></i> Pick from Docker Containers</button>
                    </div>
                    <div class="field" tourstep="requireTLS">
                        <div class="ui checkbox">
                            <input type="checkbox" id="reqTls">
                            <label>Proxy Target require TLS Connection <br><small>(i.e. Your proxy target starts with https://)</small></label>
                        </div>
                    </div>
                    <!-- Advance configs -->
                    <div class="ui basic segment advanceoptions">
                        <div id="advanceProxyRules" class="ui fluid accordion">
                            <div class="title">
                            <i class="dropdown icon"></i>
                            Advance Settings
                            </div>
                            <div class="content">
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="useStickySessionLB">
                                        <label>Sticky Session<br><small>Enable stick session on upstream load balancing</small></label>
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="enableUtm" checked>
                                        <label>Enable uptime monitor<br><small>Automatically check upstream status and switch to another if offline</small>
                                        </label>
                                    </div>
                                </div>

                                <div class="field">
                                    <label>Tags</label>
                                    <input type="text" id="proxyTags" placeholder="e.g. mediaserver, management">
                                    <small>Comma-separated list of tags for this proxy host.</small>
                                </div>
                                <div class="ui horizontal divider">
                                    <i class="ui green lock icon"></i>
                                    Security
                                </div>
                                <div class="field" tourstep="skipTLSValidation">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="skipTLSValidation">
                                        <label>Ignore TLS/SSL Verification Error<br><small>For targets that is using self-signed, expired certificate (Not Recommended)</small></label>
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="skipWebsocketOriginCheck" checked>
                                        <label>Skip WebSocket Origin Check<br><small>Allow cross-origin websocket requests (Usually not a security concern)</small></label>
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="bypassGlobalTLS">
                                        <label>Allow plain HTTP access<br><small>Allow this subdomain to be connected without TLS (Require HTTP server enabled on port 80)</small></label>
                                    </div>
                                </div>
                                <br>
                                <div class="field">
                                    <label><b>Exploits Prevention</b></label>
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="blockCommonExploits">
                                        <label>Block Common Exploits<br>
                                            <small>Detect and block common exploit payloads (SQLi, XSS, path traversal, etc.)</small>
                                        </label>
                                    </div>
                                    <br><br>
                                    <div class="ui checkbox" >
                                        <input type="checkbox" id="blockAICrawlers">
                                        <label>Block AI and Crawlers<br>
                                            <small>Block known crawlers and large-scale automated agents</small>
                                        </label>
                                    </div>
                                    <br><br>
                                    <label>Mitigation Action</label >
                                    <div class="ui fluid selection dropdown">
                                        <input type="hidden" id="mitigationAction" value="0">
                                        <i class="dropdown icon"></i>
                                        <div class="default text">Choose action when exploit / crawler detected</div>
                                        <div class="menu">
                                            <div class="item" data-value="0">404 Not Found</div>
                                            <div class="item" data-value="1">403 Forbidden</div>
                                            <div class="item" data-value="2">400 Bad Request</div>
                                            <div class="item" data-value="3">Drop Connection</div>
                                            <div class="disabled item" data-value="4">Captcha Challenge</div> <!-- Work in progress -->
                                        </div>
                                    </div>
                                    <small style="opacity:0.7;">Select how the system should respond when malicious or automated traffic is detected.</small>
                                </div>

                                <div class="ui horizontal divider">
                                    <i class="ui red ban icon"></i>
                                    Access Control
                                </div>
                                <div class="field">
                                    <label>Access Rule</label>
                                    <div class="ui selection dropdown">
                                        <input type="hidden" id="newProxyRuleAccessFilter" value="default">
                                        <i class="dropdown icon"></i>
                                        <div class="default text">Default</div>
                                        <div class="menu" id="newProxyRuleAccessList">
                                            <div class="item" data-value="default"><i class="ui yellow star icon"></i> Default</div>
                                        </div>
                                    </div>
                                    <small>Allow regional access control using blacklist or whitelist. Use "default" for "allow all".</small>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="requireBasicAuth">
                                        <label>Require Basic Auth<br><small>Require client to login in order to view the page</small></label>
                                    </div>
                                </div>
                                <div id="basicAuthCredentials" class="field">
                                    <p>Enter the username and password for allowing them to access this proxy endpoint</p>
                                    <table class="ui very basic celled table">
                                        <thead>
                                        <tr>
                                            <th>Username</th>
                                            <th>Password</th>
                                            <th>Remove</th>
                                        </tr></thead>
                                        <tbody id="basicAuthCredentialTable">
                                        <tr>
                                            <td colspan="3"><i class="ui green circle check icon"></i> No Entered Credential</td>
                                        </tr>
                                        </tbody>
                                    </table>
                                    <div class="three small fields credentialEntry">
                                        <div class="field">
                                            <input id="basicAuthCredUsername" type="text" placeholder="Username" autocomplete="off">
                                        </div>
                                        <div class="field">
                                            <input id="basicAuthCredPassword" type="password" placeholder="Password" autocomplete="off">
                                        </div>
                                        <div class="field">
                                            <button class="ui basic button" onclick="addCredentials();"><i class="blue add icon"></i> Add Credential</button>
                                        </div>
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="requireRateLimit">
                                        <label>Require Rate Limit<br><small>This proxy endpoint will be rate limited.</small></label>
                                    </div>
                                </div>
                                <div class="field">
                                    <label>Rate Limit</label>
                                    <div class="ui fluid right labeled input">
                                        <input type="number" id="proxyRateLimit" placeholder="100" min="1" max="1000" value="100">
                                        <div class="ui basic label">
                                           req / sec / IP
                                        </div>
                                    </div>
                                    <small>Return a 429 error code if request rate exceed the rate limit.</small>
                                </div>
                                <div class="ui horizontal divider">
                                    <i class="ui text file icon"></i>
                                    Logging
                                </div>
                                 <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="disableLog">
                                        <label>Disable Requests Logging<br><small>Disable requests logging for this host, recommended for high traffic sites</small>
                                        </label>
                                    </div>
                                </div>
                                <div class="field">
                                    <div class="ui checkbox">
                                        <input type="checkbox" id="disableStatisticCollection">
                                        <label>Disable Statistic Collection<br><small>Disable collecting statistics for this hostname but keep request logging</small>
                                        </label>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <br>
                    <div tourstep="newProxyRule" style="display: inline-block;">
                        <button class="ui basic button" onclick="newProxyEndpoint();"><i class="green add icon"></i> Create Endpoint</button>
                    </div>
                    <br><br>
                </div>
            </div>
        </div>
        <div class="six wide column">
            <div class="ui basic segment rulesInstructions">
                <div class="ui fluid styled accordion" id="matchingKeywordExamplesAccordion" style="background-color: transparent !important;">
                    <div class="title active" style="color: white;">
                        <i class="dropdown icon"></i>
                        Matching Keyword Examples
                    </div>
                    <div class="content active">
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui yellow star icon"></i> Domain</span><br>
                        Example of domain matching keyword:<br>
                        <code>aroz.org</code> <br>Any acess requesting aroz.org will be proxy to the IP address below<br>
                        <div class="ui divider"></div>
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui yellow star icon"></i> Subdomain</span><br>
                        Example of subdomain matching keyword:<br>
                        <code>s1.aroz.org</code> <br>Any request starting with s1.aroz.org will be proxy to the IP address below<br>
                        <div class="ui divider"></div>
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui yellow star icon"></i> Wildcard</span><br>
                        Example of wildcard matching keyword:<br>
                        <code>*.aroz.org</code> <br>Any request with a host name matching *.aroz.org will be proxy to the IP address below. Here are some examples.<br>
                        <div class="ui list">
                            <div class="item"><code>www.aroz.org</code></div>
                            <div class="item"><code>foo.bar.aroz.org</code></div>
                        </div>
                        <br>
                    </div>

                    <div class="title" style="color: white;">
                        <i class="dropdown icon"></i>
                        Remote Target Require TLS
                    </div>
                    <div class="content">
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui green lock icon"></i> Upstream TLS Requirement</span><br>
                        <p>
                            When you enable <b>Proxy Target require TLS Connection</b>, it means the <b>upstream server</b> (the target you are proxying to) requires a secure (HTTPS) connection.<br>
                            <b>This does not affect whether clients connect to this proxy endpoint using HTTP or HTTPS.</b>
                        </p>
                        <div class="ui divider"></div>
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui yellow star icon"></i> Example</span><br>
                        <code>Matching Keyword: mydomain.com<br>
                        Target: example.com:443 (TLS enabled)</code><br>
                        <ul>
                            <li>Client connects to <b>mydomain.com</b> (HTTP or HTTPS, depending on your proxy setup)</li>
                            <li>Proxy forwards requests to <b>example.com:443</b> using <b>HTTPS</b></li>
                        </ul>
                        <small>
                            Use this option if your upstream server only accepts secure connections.<br>
                            If your upstream uses a self-signed certificate, check the <b>Ignore TLS/SSL Verification Error</b> option in Advance Settings.
                        </small>
                    </div>

                    <div class="title" style="color: white;">
                        <i class="dropdown icon"></i>
                        What is Sticky Session?
                    </div>
                    <div class="content">
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui green sync icon"></i> Sticky Session (Session Affinity)</span><br>
                        <p>
                            Sticky session ensures that requests from the same client are always forwarded to the same upstream server. This is useful for applications that store session data locally and require the client to consistently connect to the same backend.<br>
                        </p>
                        <div class="ui divider"></div>
                        <span style="font-size: 1.2em; font-weight: 300;"><i class="ui yellow star icon"></i> How to Add Multiple Upstreams</span><br>
                        <ul>
                            <li>Go to <b>HTTP Proxy</b> in the sidebar.</li>
                            <li>Click <b>Edit</b> on your proxy rule.</li>
                            <li>Use the <b>Upstreams</b> section to add more upstream endpoints for load balancing.</li>
                        </ul>
                        <small>
                            Sticky session will only work if you have more than one upstream endpoint configured.
                        </small>
                    </div>
                </div>
                <script>
                    $('#matchingKeywordExamplesAccordion').accordion();
                </script>
            </div>
        </div>
    </div>
</div>
<script>

    //New Proxy Endpoint
    function newProxyEndpoint(){
        let rootname = $("#rootname").val();
        let proxyDomain = $("#proxyDomain").val();
        let useTLS = $("#reqTls")[0].checked;
        let skipTLSValidation = $("#skipTLSValidation")[0].checked;
        let bypassGlobalTLS = $("#bypassGlobalTLS")[0].checked;
        let requireBasicAuth = $("#requireBasicAuth")[0].checked;
        let proxyRateLimit = $("#proxyRateLimit").val();
        let requireRateLimit = $("#requireRateLimit")[0].checked;
        let skipWebSocketOriginCheck = $("#skipWebsocketOriginCheck")[0].checked;
        let accessRuleToUse = $("#newProxyRuleAccessFilter").val();
        let useStickySessionLB = $("#useStickySessionLB")[0].checked; 
        let tags = $("#proxyTags").val().trim();
        let enableUtm = $("#enableUtm")[0].checked;
        let disableLog = $("#disableLog")[0].checked;
        let disableStatisticCollection = $("#disableStatisticCollection")[0].checked;
        let blockCommonExploits = $("#blockCommonExploits")[0].checked;
        let blockAICrawlers = $("#blockAICrawlers")[0].checked;
        let mitigationAction = $("#mitigationAction").val();

        if (rootname.trim() == ""){
            $("#rootname").parent().addClass("error");
            return
        }else{
            $("#rootname").parent().removeClass("error");
        }

        if (proxyDomain.trim() == ""){
            $("#proxyDomain").parent().addClass("error");
            return
        }else{
            $("#proxyDomain").parent().removeClass("error");
        }

        //Create the endpoint by calling add
        $.cjax({
            url: "/api/proxy/add",
            method: "POST",
            data: {
                type: "host",
                rootname: rootname, 
                tls: useTLS, 
                ep: proxyDomain,
                tlsval: skipTLSValidation,
                bpwsorg: skipWebSocketOriginCheck,
                bypassGlobalTLS: bypassGlobalTLS,
                bauth: requireBasicAuth,
                rate: requireRateLimit,
                ratenum: proxyRateLimit,
                cred: JSON.stringify(credentials),
                access: accessRuleToUse,
                stickysess: useStickySessionLB,
                tags: tags,
                enableUtm: enableUtm,
                disableLog: disableLog,
                dStatisticCollection: disableStatisticCollection,
                blockCommonExploits: blockCommonExploits,
                blockAICrawlers: blockAICrawlers,
                mitigationAction: mitigationAction,
            },
            success: function(data){
                if (data.error != undefined){
                    msgbox(data.error, false, 5000);
                }else{
                    //Clear old data
                    $("#rootname").val("");
                    $("#proxyDomain").val("");
                    $("#proxyTags").val("");
                    $("#blockCommonExploits").prop("checked", false);
                    $("#blockAICrawlers").prop("checked", false);
                    $("#mitigationAction").parent().dropdown("set selected", "0");
                    $("#disableStatisticCollection").prop("checked", false);
                    credentials = [];
                    updateTable();
                    reloadUptimeList();
                    //Check if it is a new subdomain and TLS enabled
                    if ($("#tls").checkbox("is checked")){
                        confirmBox("Request new SSL Cert for this subdomain?", function(choice){
                            if (choice == true){
                                //Load the prefer CA from TLS page
                                let defaultCA = $("#defaultCA").dropdown("get value");
                                if (defaultCA.trim() == ""){
                                    defaultCA = "Let's Encrypt";
                                }
                                //Get a new cert using ACME
                                msgbox("Requesting certificate via " + defaultCA  +"...");
                                console.log("Trying to get a new certificate via ACME");

                                //Request ACME for certificate, see cert.html component
                                obtainCertificate(rootname, defaultCA.trim(), function(){
                                     // Renew the parent certificate list
                                    initManagedDomainCertificateList();
                                });
                            }else{
                                msgbox("Proxy Endpoint Added");
                            }
                        });
                    }else{
                        msgbox("Proxy Endpoint Added");
                    }
                }
            }
        });
        
    }

    //Clearn the proxy target value, make sure user do not enter http:// or https://
    //and auto select TLS checkbox if https:// exists
    function autoFillTargetTLS(input){
        let targetDomain = $(input).val().trim();
        if (targetDomain.startsWith("http://")){
            targetDomain = targetDomain.substr(7);
            $(input).val(targetDomain);
            $("#reqTls").parent().checkbox("set unchecked");
        }else if (targetDomain.startsWith("https://")){
            targetDomain = targetDomain.substr(8);
            $(input).val(targetDomain);
            $("#reqTls").parent().checkbox("set checked");
        }else{
            //No http or https was given. Sniff it
            autoCheckTls(targetDomain);
        }
    }
    

    //Automatic check if the site require TLS and check the checkbox if needed
    function autoCheckTls(targetDomain){
       $.cjax({
            url: "/api/proxy/tlscheck?selfsignchk=true",
            data: {url: targetDomain},
            success: function(data){
                if (data.error != undefined){
                    msgbox(data.error, false);
                }else{
                    //Check if the site require TLS
                    if (data.protocol == "https"){
                        $("#reqTls").parent().checkbox("set checked");
                    }else if (data.protocol == "http"){
                        $("#reqTls").parent().checkbox("set unchecked");
                    }
                    //Check if the site is using self-signed cert
                    if (data.selfsign){
                        $("#skipTLSValidation").parent().checkbox("set checked");
                    }else{
                        $("#skipTLSValidation").parent().checkbox("set unchecked");
                    }
                    
                }
            }
       })
    }


    function toggleBasicAuth() {
        var basicAuthDiv = document.getElementById('basicAuthOnly');
        if ($("#requireBasicAuth").parent().checkbox("is checked")) {
            $("#basicAuthCredentials").removeClass("disabled");
        } else {
            $("#basicAuthCredentials").addClass("disabled");
        }
    }
    $("#requireBasicAuth").on('change', toggleBasicAuth);
    toggleBasicAuth();
    
    function toggleRateLimit() {
        if ($("#requireRateLimit").parent().checkbox("is checked")) {
            $("#proxyRateLimit").parent().parent().removeClass("disabled");
        } else {
            $("#proxyRateLimit").parent().parent().addClass("disabled");
        }
    }
    $("#requireRateLimit").on('change', toggleRateLimit);
    toggleRateLimit();

    function toggleStatisticCollection() {
        if ($("#disableLog").parent().checkbox("is checked")) {
            $("#disableStatisticCollection").parent().checkbox("set checked");
            $("#disableStatisticCollection").parent().addClass("disabled");
        } else {
            $("#disableStatisticCollection").parent().removeClass("disabled");
        }
    }
    $("#disableLog").on('change', toggleStatisticCollection);
    toggleStatisticCollection();


    /*
        Credential Managements

    */
    let credentials = []; // Global variable to store credentials

    function addCredentials() {
        // Retrieve the username and password input values
        var username = $('#basicAuthCredUsername').val();
        var password = $('#basicAuthCredPassword').val();
        
        if(username == "" || password == ""){
            msgbox("Username or password cannot be empty", false, 5000);
            return;
        }
        
        // Create a new credential object
        var credential = {
            username: username,
            password: password
        };

        // Add the credential to the global credentials array
        credentials.push(credential);

        // Clear the input fields
        $('#basicAuthCredUsername').val('');
        $('#basicAuthCredPassword').val('');

        // Update the table body with the credentials
        updateTable();
    }

    function updateTable() {
        var tableBody = $('#basicAuthCredentialTable');
        tableBody.empty();

        if (credentials.length === 0) {
            tableBody.append('<tr><td colspan="3"><i class="ui green circle check icon"></i> No Entered Credential</td></tr>');
        } else {
            for (var i = 0; i < credentials.length; i++) {
            var credential = credentials[i];
            var username = credential.username;
            var password = credential.password.replace(/./g, '*'); // Replace each character with '*'

            var row = '<tr>' +
                '<td>' + username + '</td>' +
                '<td>' + password + '</td>' +
                '<td><button class="ui basic button" onclick="removeCredential(' + i + ');"><i class="red remove icon"></i> Remove</button></td>' +
                '</tr>';

            tableBody.append(row);
            }
        }
    }

    function removeCredential(index) {
        // Remove the credential from the credentials array
        credentials.splice(index, 1);

        // Update the table body
        updateTable();
    }

    

    //Update v3.0.0
    //Since some proxy rules now contains wildcard characters
    //all uuid are converted to hex code before use in DOM selector

    String.prototype.hexEncode = function(){
        var hex, i;

        var result = "";
        for (i=0; i<this.length; i++) {
            hex = this.charCodeAt(i).toString(16);
            result += ("000"+hex).slice(-4);
        }

        return result
    }

    String.prototype.hexDecode = function(){
        var j;
        var hexes = this.match(/.{1,4}/g) || [];
        var back = "";
        for(j = 0; j<hexes.length; j++) {
            back += String.fromCharCode(parseInt(hexes[j], 16));
        }

        return back;
    }

    /*
        Access Rule dropdown Initialization
    */

    function initNewProxyRuleAccessDropdownList(callback=undefined){
        $.get("/api/access/list", function(data){
            if (data.error == undefined){
                $("#newProxyRuleAccessList").html("");
                data.forEach(function(rule){
                    let icon = `<i class="ui grey filter icon"></i>`;
                    if (rule.ID == "default"){
                        icon = `<i class="ui yellow star icon"></i>`;
                    }else if (rule.BlacklistEnabled && !rule.WhitelistEnabled){
                        //This is a blacklist filter
                        icon = `<i class="ui red filter icon"></i>`;
                    }else if (rule.WhitelistEnabled && !rule.BlacklistEnabled){
                        //This is a whitelist filter
                        icon = `<i class="ui green filter icon"></i>`;
                    }
                    $("#newProxyRuleAccessList").append(`<div class="item" data-value="${rule.ID}">${icon} ${rule.Name}</div>`);
                });
                $("#newProxyRuleAccessFilter").parent().dropdown();
                if (callback != undefined){
                    callback();
                }
            }else{
                msgbox("Access rule load failed: " + data.error, false);
            }
        })
    }
    initNewProxyRuleAccessDropdownList();

    //Bind on tab switch events
    tabSwitchEventBind["rules"] = function(){
        //Update the access rule list
        initNewProxyRuleAccessDropdownList();
    }

    /* Docker Optimizations */
    function initDockerUXOptimizations(){
        $.get("/api/docker/available", function(dockerAvailable){
            if (dockerAvailable){
                $(".dockerOptimizations").show();
            }else{
                $(".dockerOptimizations").hide();
            }
        });
    }
    initDockerUXOptimizations();
    
    function openDockerContainersList(){
        showSideWrapper('snippet/dockerContainersList.html');
    }

    function addContainerItem(item) {
        $('#rootname').val(item.name);
        $('#proxyDomain').val(`${item.ip}:${item.port}`)
        hideSideWrapper(true);
    }
    
    /* UI Element Initialization */
    function initAdvanceSettingsAccordion(){
        function hasClickEvent(element) {
            var events = $._data(element, "events");
            return events && events.click && events.click.length > 0;
        }

         $("#advanceProxyRules").accordion();
        if (!hasClickEvent($("#advanceProxyRules"))){
            // Not sure why sometime the accordion events are not binding
            // to the DOM element. This makes sure the element is binded
            // correctly by checking it again after 300ms
            $("#advanceProxyRules").accordion();
            $("#newProxyRuleAccessFilter").parent().dropdown();
            $("#mitigationAction").parent().dropdown();
            setTimeout(function(){
                initAdvanceSettingsAccordion();
            }, 300);
        }
    }
    initAdvanceSettingsAccordion();
   
 
   
</script>